<script setup>
import { Modal } from 'ant-design-vue'
import { CaretDownFilled, CheckCircleOutlined, ColumnHeightOutlined, DeleteOutlined, DoubleRightOutlined, DownOutlined, EditOutlined, KeyOutlined, LockOutlined, PlusOutlined, ReloadOutlined, SearchOutlined, SettingOutlined, UndoOutlined, UpOutlined } from '@ant-design/icons-vue'
import { addRole, allocateRole, deleteRole, getDataList, getFuncList, getMenuList, getRoleList, getUserRole, resetPwd, saveData, saveFunc, saveMenu, updateRole } from '~@/api/system/index'

defineOptions({
  name: 'Role',
})
// 新增角色
const roleForm = ref()
const userTitle = shallowRef('')
const roleOpen = ref(false)
const allocateOpen = ref(false)
const allocateLoading = ref(false)
const editInfo = reactive({
  roleId: null,
})
// 分配菜单
const menuOpen = ref(false)
const plainOptions = shallowRef([])
// const checkedList = ref([])
// const checkAll = ref(false)
const menuState = reactive({
  indeterminate: true,
  checkAll: false,
  checkedList: [],
})
// const indeterminate = ref(false)
// 分配功能
const funcOpen = ref(false)
const funcOptions = shallowRef([])
const funcState = reactive({
  indeterminate: true,
  checkAll: false,
  checkedList: [],
})
const funcInfo = reactive({
  roleId: null,
})
// 数据权限
const dataOpen = ref(false)
const dataOptions = shallowRef([])
const dataState = reactive({
  indeterminate: true,
  checkAll: false,
  checkedList: [],
})
const dataInfo = reactive({
  roleId: null,
})
const rules = computed(() => {
  return {
    roleName: [
      { required: true, message: '请输入角色名称', trigger: 'change' },
    ],
    roleType: [
      { required: true, message: '请选择角色类型', trigger: 'change' },
    ],

  }
})
const formState = reactive({
  roleId: null,
  roleName: '',
  roleType: '',
  memo: '',

})
const allocateInfo = reactive({
  userName: '',
  realName: '',
})

const message = useMessage()
const selectedRowKeys = shallowRef([])
const roleData = shallowRef([])
const columns = shallowRef([
  {
    title: '角色编号',
    dataIndex: 'roleId',
  },
  {
    title: '角色名称',
    dataIndex: 'roleName',
  },

  {
    title: '角色类型',
    dataIndex: 'roleType',

  },
  {
    title: '备注',
    dataIndex: 'memo',
    customRender: ({ text }) => {
      if (text) {
        return text
      }
      else {
        return '--'
      }
    },
  },
  {
    title: '操作',
    dataIndex: 'action',
    align: 'center',
    fixed: 'right',
    width: '400px',

  },
])
const allocateColumns = shallowRef([
  {
    title: '角色编号',
    dataIndex: 'roleId',
  },
  {
    title: '角色名称',
    dataIndex: 'roleName',
  },
  {
    title: '角色类型',
    dataIndex: 'roleType',
  },

])
const loading = shallowRef(false)
const totalNum = shallowRef(0)
const pagination = reactive({
  pageSize: 8,
  pageSizeOptions: ['10', '20', '30', '40'],
  current: 1,
  total: totalNum,
  showSizeChanger: true,
  // showQuickJumper: true,
  showTotal: total => `总共：${total}`,
  onChange(current, pageSize) {
    pagination.pageSize = pageSize
    pagination.current = current
    init()
  },
})
const dataSource = shallowRef([])
const roleOptions = shallowRef([
  { configKey: 'admin', configValue: '管理员角色' },
  { configKey: 'common', configValue: '普通角色' },
])
const formModel = reactive({
  roleName: void 0,
})
const tableSize = ref(['large'])
const open = ref(false)

const options = computed(() => {
  return columns.value.map((item) => {
    if (item.dataIndex === 'action') {
      return {
        label: item.title,
        value: item.dataIndex,
        disabled: true,
      }
    }
    return {
      label: item.title,
      value: item.dataIndex,
    }
  })
})
const dropdownVisible = ref(false)
const getCheckList = computed(() => columns.value.map(item => item.dataIndex))
onMounted(() => {
  init()
  // getType();
  // getChannel();
})
// 处理状态
function handleStatus(text) {
  switch (text) {
    case 'ACTIVE':
      return '正常'
    case 'INACTIVE':
      return '停用'
    default:
      return '锁定'
  }
}
// 查询角色列表
async function init() {
  if (loading.value)
    return
  loading.value = true
  try {
    const { data } = await getRoleList({
      param: { ...formModel },
      page: {
        currentPage: pagination.current,
        pageSize: pagination.pageSize,
      },

    })

    dataSource.value = data.data ?? []
    // dataSource.value = data.data ?? []
    totalNum.value = data.pageInfo.total
  }
  catch (e) {
    console.log(e)
  }
  finally {
    loading.value = false
  }
}
// 搜索
async function onSearch() {
  pagination.current = 1
  await init()
}
// 删除角色
async function handleDelete(record) {
  Modal.confirm({
    title: '确认操作',
    content: `确定要删除角色 “ ${record.roleName} ” 吗？`,
    okText: '确认',
    cancelText: '取消',
    onOk() {
      return new Promise((resolve, reject) => {
        const res = deleteRole(record.roleId)
          .then((res) => {
            if (res.data.code === 'SUCCESS') {
              message.success('操作成功')
              init()
              resolve() // 关闭对话框
            }
            else {
              message.error('操作失败')
              reject() // 保持对话框打开
            }
          })
          .catch(() => {
            // message.error('操作失败')
            reject() // 保持对话框打开
          })
      })
    },
    onCancel() {
      console.log('取消操作')
    },
  })
}

// 查询角色列表
async function getRole() {
  allocateLoading.value = true
  try {
    const { data } = await getRoleList({
      param: { ...formModel },
    })

    roleData.value = data.data ?? []
    allocateLoading.value = false
  }
  catch (e) {
    console.log(e)
  }
  finally {
    allocateLoading.value = false
  }
}

// 确认分配角色
async function handleConfirm() {
  try {
    const { data } = await allocateRole({ roleIds: selectedRowKeys.value, userId: allocateInfo.userId })
    message.success('分配成功')
    init()
    allocateOpen.value = false
  }
  catch (error) {
    console.log(3333, error)
  }
  finally {
    loading.value = false
  }
}

// 分配菜单
function handleMenu(record) {
  editInfo.roleId = record.roleId
  getMenu(record)
}
// 菜单全选/反选
function onCheckAllChange(e) {
  menuState.checkedList = e.target.checked
    ? plainOptions.value.map(item => item.value)
    : []
  menuState.indeterminate = false
}

// 菜单选项变化时更新全选状态
function onChange(list) {
  menuState.checkAll = list.length === plainOptions.value.length
  menuState.indeterminate = !!list.length && list.length < plainOptions.value.length
}
// 查询当前用户所分配菜单列表
async function getMenu(record) {
  try {
    const { data } = await getMenuList({ roleId: record.roleId })

    plainOptions.value = data?.all.map(item => ({
      label: item.title,
      value: item.id,
    }))
    menuState.checkedList = data?.selectedIds
    menuOpen.value = true
  }
  catch (error) {
    // message.error('请检查表单填写是否正确')h
  }
}

// 确认分配菜单
async function confirmMenu() {
  try {
    const { data } = await saveMenu({ roleId: editInfo.roleId, resourceIds: menuState.checkedList })
    message.success('保存成功')
    init()
    menuOpen.value = false
  }
  catch (error) {
    // message.error('请检查表单填写是否正确')h
  }
}
// 分配功能
function handleFunc(record) {
  funcInfo.roleId = record.roleId
  getFunc(record)
}
// 查询当前用户所分配功能列表
async function getFunc(record) {
  try {
    const { data } = await getFuncList({ roleId: record.roleId })
    funcOptions.value = data?.all.map(item => ({
      label: item.funcName,
      value: item.funcId,
    }))
    funcState.checkedList = data?.selectedIds
    funcOpen.value = true
  }
  catch (error) {
    // message.error('请检查表单填写是否正确')h
  }
}
// 功能全选/反选
function onCheckAllFuncChange(e) {
  funcState.checkedList = e.target.checked
    ? funcOptions.value.map(item => item.value)
    : []
  funcState.indeterminate = false
}

// 功能选项变化时更新全选状态
function onFuncChange(list) {
  funcState.checkAll = list.length === funcOptions.value.length
  funcState.indeterminate = !!list.length && list.length < funcOptions.value.length
}
// 确认授权功能
async function confirmFunc() {
  try {
    const { data } = await saveFunc({ roleId: funcInfo.roleId, functionIds: funcState.checkedList })
    message.success('保存成功')
    init()
    funcOpen.value = false
  }
  catch (error) {
    // message.error('请检查表单填写是否正确')h
  }
}

// 分配数据全选
function handleData(record) {
  dataInfo.roleId = record.roleId
  getData(record)
}
// 查询当前用户所分配数据权限列表
async function getData(record) {
  try {
    const { data } = await getDataList({ roleId: record.roleId })
    dataOptions.value = data?.all.map(item => ({
      label: item.appName,
      value: item.appId,
    }))
    dataState.checkedList = data?.selectedIds
    dataOpen.value = true
  }
  catch (error) {
    // message.error('请检查表单填写是否正确')h
  }
}
// 功能全选/反选
function onCheckAllDataChange(e) {
  dataState.checkedList = e.target.checked
    ? dataOptions.value.map(item => item.value)
    : []
  dataState.indeterminate = false
}

// 功能选项变化时更新全选状态
function onDataChange(list) {
  dataState.checkAll = list.length === dataOptions.value.length
  dataState.indeterminate = !!list.length && list.length < dataOptions.value.length
}
// 确认授权数据权限
async function confirmData() {
  try {
    const { data } = await saveData({ roleId: dataInfo.roleId, appIds: dataState.checkedList })
    message.success('保存成功')
    init()
    dataOpen.value = false
  }
  catch (error) {
    // message.error('请检查表单填写是否正确')h
  }
}

function onSelectChange(value) {
  console.log('selectedRowKeys changed: ', value)
  selectedRowKeys.value = value
}
function handleReturn() {
  open.value = false
}
// 打开新增角色弹窗
function addRoleModal() {
  if (roleForm.value) {
    roleForm.value.resetFields()
  }
  resetRole()
  userTitle.value = '新增角色'
  roleOpen.value = true
}

// 重置角色信息
function resetRole() {
  formState.roleId = void 0
  formState.roleName = void 0
  formState.roleType = void 0
  formState.memo = void 0
}
// 确认新增角色
async function handleOk() {
  try {
    await roleForm.value.validate()
    if (formState.roleId) {
      const { data } = await updateRole(formState)
      if (data.code === 'SUCCESS') {
        roleOpen.value = false
        message.success('保存成功')
        init()
      }
    }
    else {
      const { data } = await addRole(formState)
      if (data.code === 'SUCCESS') {
        roleOpen.value = false
        message.success('新增成功')
        init()
      }
    }
  }
  catch (error) {
    // message.error('请检查表单填写是否正确')
  }
}
// 编辑角色
async function handleEdit(record) {
  roleOpen.value = true
  formState.roleId = record.roleId
  formState.roleName = record.roleName
  formState.roleType = record.roleType
  formState.memo = record.memo
  userTitle.value = '编辑角色'
}
function handleSizeChange(e) {
  tableSize.value[0] = e.key
}
function filterAction(value) {
  return columns.value.filter((item) => {
    if (value.includes(item.dataIndex))
      return true

    return false
  })
}
const filterColumns = ref(filterAction(getCheckList.value))
function handleCheckAllChange(e) {
  Object.assign(state, {
    checkList: e.target.checked ? getCheckList.value : [],
    indeterminate: true,
  })
  filterColumns.value = e.target.checked ? filterAction(getCheckList.value) : filterColumns.value.filter(item => item.dataIndex === 'action')
}
watch(
)
const expand = ref(false)
</script>

<template>
  <page-container>
    <a-card mb-4>
      <a-form :model="formModel" layout="inline">
        <a-form-item name="userName" label="角色名称">
          <a-input v-model:value="formModel.roleName" placeholder="请输入角色名称" allow-clear />
        </a-form-item>
        <a-form-item>
          <a-space flex justify-end w-full>
            <a-button type="primary" @click="onSearch">
              <SearchOutlined />查询
            </a-button>
            <a-button type="primary" class="ml-2" ghost @click="addRoleModal">
              <PlusOutlined />新增
            </a-button>
          </a-space>
        </a-form-item>
      </a-form>
    </a-card>

    <a-card>
      <a-table bordered :loading="loading" :columns="filterColumns" :scroll="{ x: 1000 }" :data-source="dataSource" :pagination="pagination">
        <template #bodyCell="{ column, record }">
          <template v-if="column.dataIndex === 'balance'">
            <span :style="{ color: record.balance < 0 ? 'red' : 'black' }">{{ Number(record.balance).toFixed(2) }}</span>
          </template>

          <template v-else-if="column.dataIndex === 'status'">
            <a-tag
              :color="record.status === 'ACTIVE' ? 'geekblue' : (record.status === 'INACTIVE' ? 'red' : 'volcano')"
            >
              {{ handleStatus(record.status) }}
            </a-tag>
          </template>
          <template v-else-if="column.dataIndex === 'certNo'">
            {{ handleCertcard(record.certNo) }}
          </template>
          <template v-else-if="column.dataIndex === 'action'">
            <div class="action flex flex-center">
              <a @click="handleMenu(record)">分配菜单</a>
              <span class="middle-line">|</span>
              <a @click="handleFunc(record)">分配功能</a>
              <span class="middle-line">|</span>
              <a @click="handleData(record)">数据权限</a>
              <span class="middle-line">|</span>
              <a-button type="link" @click="handleEdit(record)">
                <EditOutlined />
              </a-button>
              <span class="middle-line">|</span>
              <a-button type="link" @click="handleDelete(record)">
                <DeleteOutlined />
              </a-button>
            </div>
          </template>
        </template>
      </a-table>
    </a-card>
    <!-- 新增角色 -->
    <a-modal v-model:open="roleOpen" :mask-closable="false" width="700px" :title="userTitle" :body-style="{ paddingTop: '25px', paddingBottom: '30px' }" ok-text="保存" @ok="handleOk">
      <a-form
        ref="roleForm"
        :model="formState"
        :rules="rules"
        name="basic"
        :label-col="{ span: 5 }"
        :wrapper-col="{ span: 16 }"
        autocomplete="off"
      >
        <a-row>
          <a-col :span="24">
            <a-form-item name="roleName" label="角色名称">
              <a-input v-model:value="formState.roleName" placeholder="请输入角色名称" allow-clear />
            </a-form-item>
            <a-form-item name="roleType" label="角色类型">
              <a-select v-model:value="formState.roleType" placeholder="请选择" allow-clear>
                <a-select-option v-for="item in roleOptions" :key="item.configKey" :value="item.configKey">
                  {{ item.configValue }}
                </a-select-option>
              </a-select>
            </a-form-item>
            <a-form-item label="备注">
              <a-textarea v-model:value="formState.memo" :rows="4" />
            </a-form-item>
          </a-col>
        </a-row>
      </a-form>
    </a-modal>
    <!-- 分配菜单 -->
    <a-modal v-model:open="menuOpen" :mask-closable="false" width="1000px" title="分配菜单" :body-style="{ paddingTop: '5px', paddingBottom: '50px' }" ok-text="确定" @ok="confirmMenu">
      <div>
        <a-checkbox
          v-model:checked="menuState.checkAll"
          :indeterminate="menuState.indeterminate"
          @change="onCheckAllChange"
        >
          全选
        </a-checkbox>
      </div>
      <a-divider />
      <a-checkbox-group v-model:value="menuState.checkedList" class="menubox" :options="plainOptions" @change="onChange" />
    </a-modal>
    <!-- 分配功能 -->
    <a-modal v-model:open="funcOpen" :mask-closable="false" width="1000px" title="分配功能" :body-style="{ paddingTop: '5px', paddingBottom: '50px' }" ok-text="确定" @ok="confirmFunc">
      <div>
        <a-checkbox
          v-model:checked="funcState.checkAll"
          :indeterminate="funcState.indeterminate"
          @change="onCheckAllFuncChange"
        >
          全选
        </a-checkbox>
      </div>
      <a-divider />
      <a-checkbox-group v-model:value="funcState.checkedList" class="menubox" :options="funcOptions" @change="onFuncChange" />
    </a-modal>
    <!-- 数据权限 -->
    <a-modal v-model:open="dataOpen" :mask-closable="false" width="1200px" title="数据权限" :body-style="{ paddingTop: '5px', paddingBottom: '50px' }" ok-text="确定" @ok="confirmData">
      <div>
        <a-checkbox
          v-model:checked="dataState.checkAll"
          :indeterminate="dataState.indeterminate"
          @change="onCheckAllDataChange"
        >
          全选
        </a-checkbox>
      </div>
      <a-divider />
      <div style="height: 450px;overflow-y:scroll;">
        <a-checkbox-group v-model:value="dataState.checkedList" class="menubox" :options="dataOptions" @change="onDataChange" />
      </div>
    </a-modal>
    <!-- 分配角色 -->
    <a-modal v-model:open="allocateOpen" :mask-closable="false" width="1000px" title="分配角色" :body-style="{ paddingTop: '25px', paddingBottom: '50px' }" ok-text="确定" @ok="handleConfirm">
      <div class="mb-5" style="font-size: 16px;">
        <span class="mr-10 ">角色昵称：<span class="font-600" style="color:#172b4d">{{ allocateInfo.realName }}</span></span>   登录账号：<span class="font-600" style="color:#172b4d">{{ allocateInfo.userName }}</span>
      </div>
      <a-table :pagination="false" row-key="roleId" :row-selection="{ selectedRowKeys, onChange: onSelectChange }" bordered :loading="allocateLoading" :columns="allocateColumns" :data-source="roleData" />
    </a-modal>
  </page-container>
</template>

    <style lang="less" scoped>
      :deep(.ant-btn){
        padding: 4px 8px;
      }
      .ant-divider-horizontal{
        margin: 15px 0;
      }
      .line{
        color:#1677ff;
      }
      .userTitle{
        color:gray;
        width: 100%;
        padding:5px 0;
        border-bottom:1px solid #f1eded;
        margin-bottom: 20px;
      }
      .red{
        color:red;
        /* color:#ff4d4f; */
      }
      .card-title{
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
        flex: auto;
        color: rgba(0, 0, 0, 0.88);
        font-weight: 600;
        font-size: 16px;
        line-height: 1.5;
      }
    @media screen and (max-width: 1200px) and (min-width: 992px) {
      .activeCard {
        margin-bottom: 24px;
      }
      .members {
        margin-bottom: 0;
      }
      .extraContent {
        margin-left: -44px;
        .statItem {
          padding: 0 16px;
        }
      }
    }

    @media screen and (max-width: 992px) {
      .activeCard {
        margin-bottom: 24px;
      }
      .members {
        margin-bottom: 0;
      }
      .extraContent {
        float: none;
        margin-right: 0;
        .statItem {
          padding: 0 16px;
          text-align: left;
          &::after {
            display: none;
          }
        }
      }
    }

    @media screen and (max-width: 768px) {
      .extraContent {
        margin-left: -16px;
      }
      .projectList {
        .projectGrid {
          width: 50%;
        }
      }
    }

    @media screen and (max-width: 576px) {
      .pageHeaderContent {
        display: block;
        .content {
          margin-left: 0;
        }
      }
      .extraContent {
        .statItem {
          float: none;
        }
      }
    }

    @media screen and (max-width: 480px) {
      .projectList {
        .projectGrid {
          width: 100%;
        }
      }
    }
    </style>

    <style>
      [class^="ant-checkbox-group"] [class*=" ant-checkbox-group"]{
        margin:10px !important;
        width:190px !important;
      }
</style>
